﻿using System.Threading;

namespace System
{
    ///<summary>
    /// Цыклы алгоритмы
    ///</summary>
    public static class Cycle
    {
        /// <summary>
        /// Циклическое выполнение действия в параллельном режиме
        /// </summary>
        /// <param name="cycle">Выполняемое действие</param>
        /// <param name="N">Число повторений</param>
        public static void ForParallel(this Action<int, int> cycle, int N)
        {
            ForParallel(cycle, N, true);
        }

        /// <summary>
        /// Циклическое выполнение действия в параллельном режиме
        /// </summary>
        /// <param name="cycle">Выполняемое действие</param>
        /// <param name="N">Число повторений</param>
        /// <param name="Whait">Оиждать давершения цикла?</param>
        public static void ForParallel(this Action<int, int> cycle, int N, bool Whait)
        {
            if(Whait)
            {
                var whait = new ManualResetEvent[N];
                for(var i = 0; i < N; i++)
                {
                    var lv_I = i;
                    var w = whait[i] = new ManualResetEvent(false);
                    ThreadPool.QueueUserWorkItem(o =>
                    {
                        cycle(lv_I, N);
                        w.Set();
                    });
                }
                for(var i = 0; i < N; i++)
                    whait[i].WaitOne();
            }
            else
                for(var i = 0; i < N; i++)
                {
                    var lv_I = i;
                    ThreadPool.QueueUserWorkItem(o => cycle(lv_I, N));
                }

        }

        /// <summary>
        /// Циклическое выполнение действия в последовательном режиме
        /// </summary>
        /// <param name="cycle">Выполняемое действие</param>
        /// <param name="N">Число повторений</param>
        public static void ForLinear(this Action<int, int> cycle, int N)
        {
            for(var i = 0; i < N; i++)
                cycle(i, N);
        }
    }
}
